package cn.com.wxd.util.action;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.wxd.biz.log.AccessLogService;
import cn.com.wxd.biz.log.AccessLogServiceImpl;
import cn.com.wxd.entity.log.AccesslogTempInfo;
import cn.com.wxd.entity.user.AccountInfo;
import cn.com.wxd.service.address.AddressBean;
import cn.com.wxd.service.address.AddressService;
import cn.com.wxd.common.DateUtil;
import cn.com.wxd.common.GlobalConstant;
import cn.com.wxd.util.RequestUtil;
import cn.com.wxd.util.framework.LocalCacheUtil;
import cn.com.wxd.util.SpringContextHolder;
import cn.com.wxd.util.user.UserCoreUtil;

/**
 * Title:用户访问记录工具类
 * Description:此类本身是一个缓存类，缓存了一些数据，
 * <p>
 * Company: Amumu管理平台
 * Copyright: Copyright (c) 2015
 * All right reserved.
 * Created time: 2016-4-14 下午3:08:03
 *
 * @author WangXuDong
 * @version 1.0
 */
public class AccessLogUtil {
    private static final Logger log = LoggerFactory.getLogger(AccessLogUtil.class);
    private static int onlineUser = 0;
    private static int tatorAccessVolume = 0;
    private static long totorreftimetemp = 0;
    private static int todayAccessVolume = 0;
    private static long todayreftimetemp = 0;

    /**
     * 添加一条访问记录到数据库临时表中如果存在则不会添加
     *
     * @param request
     *
     * @return 0添加成功 1存在 -1失败
     */
    public static int addAccessLogtoTemp(HttpServletRequest request) {

        //获取IP
        String ip = RequestUtil.getRemortIP(request);
        //先从缓存中查找数据，减少数据库的访问程度，并且持久化
        String str = String.valueOf(LocalCacheUtil.getInstance().get(GlobalConstant.ACCESSLOGCACHENAME, ip));
        if (str.equalsIgnoreCase("ip")) {
            return 1;
        }

        //从Spring中获取业务逻辑层的实例
        AccessLogService als =
                (AccessLogServiceImpl) SpringContextHolder.getBean("accessLogService");
        if (als == null) {
            return -1;
        } else {
            // 从数据库取数据
            int count = als.getAccessRecodeCountByIp(ip);
            if (count <= 0) {
                AccesslogTempInfo ati = new AccesslogTempInfo();
                ati.setIp(ip);
                ati.setDateTime(DateUtil.getDatetimeStr());
                ati.setRequestUrl(request.getRequestURI());
                try {
                    // 或取这个人的地址信息并保存到访问日志中
                    AddressService as = new AddressService();
                    AddressBean ab = as.getAddress(request, "utf-8");
                    if (ab != null) {
                        ati.setCountry(ab.getCountry());
                        ati.setArea(ab.getArea());
                        ati.setCity(ab.getCity());
                        ati.setProvince(ab.getProvince());
                    }
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
                //添加到数据库中
                if (als.addAccessRecode(ati)) {

                    // 如果是当天第一访问，则加入数据库和缓存中
                    LocalCacheUtil.getInstance().put(GlobalConstant.ACCESSLOGCACHENAME, ip, "ip");
                    return 0;
                }
            } else {
                // 如果是当天第一访问，则加入数据库和缓存中
                LocalCacheUtil.getInstance().put(GlobalConstant.ACCESSLOGCACHENAME, ip, "ip");
                return 1;
            }
        }
        return -1;
    }

    /**
     * 添加一条用户操作日志
     *
     * @param request 用户信息
     * @param operate 操作
     *
     * @return 返回0成功，返回-1失败
     */
    public static int addUserOperationLog(HttpServletRequest request, String operate) {
        AccountInfo accountInfo = UserCoreUtil.getLoginAccount(request);
        return addUserOperationLog(accountInfo, operate);
    }

    /**
     * 添加一条用户操作日志
     *
     * @param accountInfo
     * @param operate     操作
     *
     * @return 返回0成功，返回-1失败
     */
    public static int addUserOperationLog(AccountInfo accountInfo, String operate) {
        try {
            AccessLogService als = SpringContextHolder
                    .getBean("accessLogService", AccessLogServiceImpl.class); //从Spring中获取业务逻辑层的实例

            boolean result = als.addUserLog(accountInfo, operate);
            if (result) {
                return 0;
            }
        } catch (Exception e) {
            log.error("用户日志:" + operate + "失败！" + e.getMessage(), e);
        }
        return -1;
    }

    /**
     * 获取在线人数
     *
     * @return
     */
    public static int getOnlineUser() {
        if (onlineUser < 0) {
            onlineUser = 0;
        }
        return onlineUser;
    }

    /**
     * 设置在线人数
     *
     * @param onlineUser
     */
    public static void setOnlineUser(int onlineUser) {
        if (onlineUser < 0) {
            onlineUser = 0;
        }
        AccessLogUtil.onlineUser = onlineUser;
    }

    /**
     * 获取今日访问量
     * 数据每5分钟刷新一次
     *
     * @return
     */
    public static int getToDayAccessVolume() {
        AccessLogService als = (AccessLogServiceImpl) SpringContextHolder
                .getBean("accessLogService"); //从Spring中获取业务逻辑层的实例
        //根据时间戳判断是否从数据库读取最新今日访问量
        //总访问量每5分钟刷新一次
        if (todayreftimetemp <= 0 || System.currentTimeMillis() - todayreftimetemp > 300000) {
            todayAccessVolume = als.getPVofToday();
            todayreftimetemp = System.currentTimeMillis();
        }
        return todayAccessVolume + onlineUser;
    }

    /**
     * 获取总访问量
     * 数据每24小时刷新一次，但并不会影响访问量等信息的正确性
     *
     * @return
     */
    public static int getTatorAccessVolume() {
        AccessLogService als = (AccessLogServiceImpl) SpringContextHolder
                .getBean("accessLogService"); //从Spring中获取业务逻辑层的实例
        //根据时间戳判断是否从数据库读取最新今日访问量
        //总访问量每24小时刷新一次
        if (totorreftimetemp <= 0 || System.currentTimeMillis() - totorreftimetemp > 86400000) {
            tatorAccessVolume = als.getVisitorVolume();
            totorreftimetemp = System.currentTimeMillis();
        }
        return tatorAccessVolume + todayAccessVolume + onlineUser;
    }
}
